package cn.jingyuan.bee.utils.convert;

import cn.jingyuan.bee.utils.StringUtils;

/**
 * 将浮点数类型的 number 转换成英语的表达方式 <br>
 * 参考博客：http://blog.csdn.net/eric_sunah/article/details/8713226
 */
public class NumberWordFormat {

    private static final String[] NUMBER = new String[]{"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
            "EIGHT", "NINE"};

    private static final String[] NUMBER_TEEN = new String[]{"TEN", "ELEVEN", "TWELEVE", "THIRTEEN", "FOURTEEN",
            "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"};

    private static final String[] NUMBER_TEN = new String[]{"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY",
            "SEVENTY", "EIGHTY", "NINETY"};

    private static final String[] NUMBER_MORE = new String[]{"", "THOUSAND", "MILLION", "BILLION"};

    /**
     * 将阿拉伯数字转为英文表达式
     *
     * @param x 阿拉伯数字，可以为 {@link Number} 对象，也可以是普通对象，最后会使用字符串方式处理
     *
     * @return 英文表达式
     */
    public static String format(Object x) {
        if (x != null) {
            return format(x.toString());
        } else {
            return "";
        }
    }

    /**
     * 将阿拉伯数字转为英文表达式
     *
     * @param x 阿拉伯数字字符串
     *
     * @return 英文表达式
     */
    private static String format(String x) {
        // 取小数点位置
        int z = x.indexOf(".");
        String lstr, rstr = "";

        // 看是否有小数，如果有，则分别取左边和右边
        if (z > -1) {
            lstr = x.substring(0, z);
            rstr = x.substring(z + 1);
        } else {
            // 否则就是全部
            lstr = x;
        }

        // 对左边的字串取反
        String lstrrev = StringUtils.reverse(lstr);

        // 定义 5 个字串变量来存放解析出来的叁位一组的字串
        String[] a = new String[5];

        switch (lstrrev.length() % 3) {
            case 1:
                lstrrev += "00";
                break;
            case 2:
                lstrrev += "0";
                break;
        }

        // 用来存放转换後的整数部分
        StringBuilder lm = new StringBuilder();
        for (int i = 0; i < lstrrev.length() / 3; i++) {
            // 截取第一个叁位
            a[i] = StringUtils.reverse(lstrrev.substring(3 * i, 3 * i + 3));

            // 用来避免这种情况：1000000 = one million
            if (!a[i].equals("000")) {
                // thousand only
                if (i != 0) {
                    lm.insert(0, transThree(a[i]) + " " + parseMore(i) + " "); // 加:
                    // thousand、million、billion
                } else {
                    // 防止 i=0 时， 在多加两个空格.
                    lm = new StringBuilder(transThree(a[i]));
                }
            } else {
                lm.append(transThree(a[i]));
            }
        }

        // 用来存放转换後小数部分
        String xs = "";
        if (z > -1) {
            // 小数部分存在时转换小数
            xs = "AND CENTS " + transTwo(rstr) + " ";
        }
        return lm.toString().trim() + " " + xs + "ONLY";
    }

    private static String parseFirst(String s) {
        return NUMBER[Integer.parseInt(s.substring(s.length() - 1))];
    }

    private static String parseTeen(String s) {
        return NUMBER_TEEN[Integer.parseInt(s) - 10];
    }

    private static String parseTen(String s) {
        return NUMBER_TEN[Integer.parseInt(s.substring(0, 1)) - 1];
    }

    private static String parseMore(int i) {
        return NUMBER_MORE[i];
    }

    // 两位
    private static String transTwo(String s) {
        String value;
        // 判断位数
        if (s.length() > 2) {
            s = s.substring(0, 2);
        } else if (s.length() < 2) {
            s = "0" + s;
        }

        // 07 - seven 是否小於 10
        if (s.startsWith("0")) {
            value = parseFirst(s);
        } else if (s.startsWith("1")) {
            // 17 seventeen 是否在 10 和 20 之间
            value = parseTeen(s);
        } else if (s.endsWith("0")) {
            // 是否在 10 与 100 之间的能被 10 整除的数
            value = parseTen(s);
        } else {
            value = parseTen(s) + " " + parseFirst(s);
        }
        return value;
    }

    /**
     * 制作叁位的数
     *
     * @param s 参数
     *
     * @return 结果字符串
     */
    private static String transThree(String s) {
        String value;
        if (s.startsWith("0")) {// 是否小於 100
            value = transTwo(s.substring(1));
        } else if (s.substring(1).equals("00")) {// 是否被 100 整除
            value = parseFirst(s.substring(0, 1)) + " HUNDRED";
        } else {
            value = parseFirst(s.substring(0, 1)) + " HUNDRED AND " + transTwo(s.substring(1));
        }
        return value;
    }

}